﻿using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Cmp;
using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

namespace ZL_Framework
{
    /// <summary>
    /// 序列帧动画
    /// </summary>
    public class SequenceFrameAnim : MonoBehaviour
    {
        public enum AnimType
        {
            /// <summary>
            /// UI_Imaage序列帧
            /// </summary>
            UGUI_IMAGE,
            /// <summary>
            /// UI_RawImaage序列帧
            /// </summary>
            UGUI_RAWIMAGE,
            /// <summary>
            /// Sprite序列帧
            /// </summary>
            SPRITE
        }


        /// <summary>
        /// 播放状态
        /// </summary>
        public bool IsPlaying
        {
            get
            {
                return isPlay;
            }
        }

        public AnimType animType;
        public bool isLoop;
        [Tooltip("播放次数")]
        public int playCount = 1;
        public bool isAwakePlay;
        [Tooltip("播放完成是否自动销毁此物体")]
        public bool isAutoDestroy = true;
        [Tooltip("动画播放速度（帧）")]
        public float animSpeed = 10;  //动画播放速度 默认1秒播放10帧图片
        public Sprite[] SpriteArray; //序列帧数组  UGUI_IMAGE 和 SPRITE模式使用
        public Texture2D[] TexArray; //序列帧数组  UGUI_RAWIMAGE 模式使用
        public UnityEvent animComplete = new UnityEvent();

        private bool isPlay;
        private int curPlayCount;
        private float animTimeInterval = 0;  //帧与帧间隔的时间
        private SpriteRenderer animRenderer;//动画载体的渲染器
        private Image animImage;
        private RawImage animRawImage;

        private int frameIndex = 0;  //帧索引
        private int animLength = 0;  //多少帧
        private float animTimer = 0; //动画时间计时器

        private void Start()
        {
            if (animSpeed < 0)
            {
                Debug.LogError("animSpeed 不能小于0");
                return;
            }
            if (isAwakePlay)
            {
                PlayAnim(_playCount: playCount);
            }
        }

        private void Update()
        {
            if (!isPlay)
            {
                return;
            }
            RefreshAnimFrame();
        }

        private void RefreshAnimFrame()
        {
            if (Application.isPlaying)
            {
                animTimer += Time.deltaTime;
                if (animTimer > animTimeInterval)
                {
                    animTimer -= animTimeInterval;//当计时器减去一个周期的时间
                    if (isLoop)
                    {
                        frameIndex %= animLength;//判断是否到达最大帧数，到了就从新开始  这里是循环播放的
                    }
                    else
                    {
                        if (frameIndex > SpriteArray.Length - 1)
                        {
                            curPlayCount++;
                            frameIndex = 0;
                            if (curPlayCount == playCount)
                            {
                                isPlay = false;
                                animComplete.Invoke();
                                if (isAutoDestroy)
                                {
                                    Destroy(gameObject);
                                }
                                return;
                            }
                        }
                    }
                    switch (animType)
                    {
                        case AnimType.UGUI_IMAGE:
                            animImage.sprite = SpriteArray[frameIndex];
                            break;
                        case AnimType.UGUI_RAWIMAGE:
                            animRawImage.texture = TexArray[frameIndex];
                            break;
                        case AnimType.SPRITE:
                            animRenderer.sprite = SpriteArray[frameIndex]; //替换图片实现动画
                            break;
                        default:
                            break;
                    }
                    frameIndex++;//当帧数自增（播放下一帧）
                }
            }
        }

        /// <summary>
        /// 播放动画
        /// 预设挂好此脚本时可直接调用此方法
        /// </summary>
        /// <param name="_animAction"></param>
        public void PlayAnim(UnityAction _animAction = null, int _playCount = 1, bool _isAutoDestroy = true)
        {
            switch (animType)
            {
                case AnimType.UGUI_IMAGE:
                    animImage = GetComponent<Image>();
                    break;
                case AnimType.UGUI_RAWIMAGE:
                    animRawImage = GetComponent<RawImage>();
                    break;
                case AnimType.SPRITE:
                    animRenderer = GetComponent<SpriteRenderer>();
                    break;
                default:
                    break;
            }
            if (_animAction != null)
            {
                animComplete.AddListener(_animAction);
            }
            SetAnimSpeed();
            playCount = _playCount;
            isAutoDestroy = _isAutoDestroy;
            isPlay = true;
        }

        /// <summary>
        /// 暂停
        /// </summary>
        public void PauseAnim()
        {
            isPlay = false;
        }

        /// <summary>
        /// 继续
        /// </summary>
        public void ContinueAnim()
        {
            isPlay = true;
        }

        /// <summary>
        /// 停止
        /// </summary>
        public void StopAnim()
        {
            frameIndex = 0;
            isPlay = false;
        }

        /// <summary>
        /// 重新播放
        /// </summary>
        public void ReplayAnim()
        {
            frameIndex = 0;
            isPlay = true;
        }

        /// <summary>
        /// 播放UI_Image序列帧
        /// 动态添加此脚本时调用
        /// </summary>
        /// <param name="_animImage">Image载体</param>
        /// <param name="_sprites">帧图片列表</param>
        /// <param name="_isLoop">是否循环播放</param>
        /// <param name="_animSpeed">播放速度</param>
        /// <param name="_animAction">回调</param>
        public void PlayUIImgAnim(Image _animImage, Sprite[] _sprites, bool _isLoop, float _animSpeed = 10, UnityAction _animAction = null, int _playCount = 1, bool _isAutoDestroy = true)
        {
            animType = AnimType.UGUI_IMAGE;
            animImage = _animImage;
            SetAnimValue(_sprites, null, _isLoop, _animSpeed, _animAction, animType, _playCount, _isAutoDestroy);
        }

        /// <summary>
        /// 播放UI_RawImage序列帧
        /// 动态添加此脚本时调用
        /// </summary>
        /// <param name="_animImage">Image载体</param>
        /// <param name="_sprites">帧图片列表</param>
        /// <param name="_isLoop">是否循环播放</param>
        /// <param name="_animSpeed">播放速度</param>
        /// <param name="_animAction">回调</param>
        public void PlayUIRawImgAnim(RawImage _animRawImage, Texture2D[] _tex, bool _isLoop, float _animSpeed = 10, UnityAction _animAction = null, int _playCount = 1, bool _isAutoDestroy = true)
        {
            animType = AnimType.UGUI_RAWIMAGE;
            animRawImage = _animRawImage;
            SetAnimValue(null, _tex, _isLoop, _animSpeed, _animAction, animType, _playCount, _isAutoDestroy);
        }

        /// <summary>
        /// 播放Sprite序列帧
        /// 动态添加此脚本时调用
        /// </summary>
        /// <param name="_animImage">SpriteRenderer载体</param>
        /// <param name="_sprites">帧图片列表</param>
        /// <param name="_isLoop">是否循环播放</param>
        /// <param name="_animSpeed">播放速度</param>
        /// <param name="_animAction">回调</param>
        public void PlaySpriteAnim(SpriteRenderer _animRenderer, Sprite[] _sprites, bool _isLoop, float _animSpeed = 10, UnityAction _animAction = null, int _playCount = 1, bool _isAutoDestroy = true)
        {
            animType = AnimType.SPRITE;
            animRenderer = _animRenderer;
            SetAnimValue(_sprites, null, _isLoop, _animSpeed, _animAction, animType, _playCount, _isAutoDestroy);
        }

        private void SetAnimValue(Sprite[] _sprites, Texture2D[] _tex, bool _isLoop, float _animSpeed, UnityAction _animAction, AnimType _type, int _playCount = 1, bool _isAutoDestroy = true)
        {
            if (_type == AnimType.UGUI_RAWIMAGE)
            {
                TexArray = _tex;
            }
            else
            {
                SpriteArray = _sprites;
            }
            isLoop = _isLoop;
            animSpeed = _animSpeed;
            if (_animAction != null)
            {
                animComplete.AddListener(_animAction);
            }
            isAutoDestroy = _isAutoDestroy;
            playCount = _playCount;
            SetAnimSpeed();
            isPlay = true;
        }

        private void SetAnimSpeed()
        {
            animTimeInterval = 1 / animSpeed;//得到每一帧的时间间隔
            animLength = SpriteArray.Length; //得到帧数
        }

        private void OnDestroy()
        {
            animComplete.RemoveAllListeners();
            isPlay = false;
            animRenderer = null;
            animImage = null;
            animRawImage = null;
            animTimeInterval = 0;
            frameIndex = 0;
            animLength = 0;
            animTimer = 0;
            curPlayCount = 0;
            playCount = 1;
            SpriteArray = null;
            TexArray = null;
        }
    }
}